home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Graphics⁄Sound / crit / draw.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-05-24  |  5.3 KB  |  218 lines  |  [TEXT/????]

  1. /*
  2.  * draw.c - window handling for the project critic.
  3.  *
  4.  */
  5.  
  6. #include <memory.h>
  7. #include <quickdraw.h>
  8. #include <window.h>
  9. #include <osutil.h>
  10. #include <event.h>
  11. #include <toolutil.h>
  12. #include <resource.h>
  13. #include <segment.h>
  14.  
  15. #include "progerr.h"
  16. #include "critic.h"
  17.  
  18. /*
  19.  * BASEPICT - resource ID of the first Pict to get.
  20.  * Pict numbers are sequential, in the following order:
  21.  *    Facing right, frame 1
  22.  *    Facing right, frame 2
  23.  *    Facing left, frame 1
  24.  *    Facing left, frame 2
  25.  */
  26.  
  27. #define BASEPICT    256
  28.  
  29. #define NUM_DIRS    2    /* directions: 0 == to the right; 1 == opposite    */
  30. #define FRAMES_PER    2    /* frames per direction                */
  31.  
  32. PicHandle apict[NUM_DIRS][FRAMES_PER];    /* pictures to draw            */
  33.  
  34. /*
  35.  * vhinc[] - for each direction, the vert and horz movement per frame.
  36.  */
  37.  
  38. Point vhinc[NUM_DIRS] = {
  39.     {0,  12},
  40.     {0, -12}
  41. };
  42.  
  43. BitMap offscreen;    /* off-screen bitmap for cheap animation        */
  44.  
  45. int curdir;        /* current direction of movement            */
  46. int curframe;        /* current frame for this direction            */
  47. Rect currect;        /* rect surrounding the current pict            */
  48.  
  49. /*
  50.  * doc_init() - initialize the data needed to draw the screen.
  51.  * Get all of the pictures to draw,
  52.  * allocate the offscreen bitmap and draw into it.
  53.  */
  54.  
  55. doc_init()
  56. {
  57.     int resid;        /* Resource ID of the current Pict to get        */
  58.     BitMap oldmap;    /* windoc's previous bitmap                */
  59.     RgnHandle oldvis;    /* windoc's previous visible region            */
  60.     GrafPtr saveport;
  61.  
  62.     topLeft(offscreen.bounds) = topLeft(windoc->portBits.bounds);
  63.     botRight(offscreen.bounds) = botRight(windoc->portBits.bounds);
  64.     offscreen.rowBytes = windoc->portBits.rowBytes;
  65.  
  66.     offscreen.baseAddr = (QDPtr)
  67.       NewPtr((Size) ((int) offscreen.rowBytes *
  68.       (offscreen.bounds.bottom - offscreen.bounds.top)));
  69.     if (!offscreen.baseAddr) {
  70.     progstop(PE_NOMEM);
  71.     ExitToShell();
  72.     }
  73.  
  74.     /*
  75.      * get handles for the background pictures
  76.      */
  77.  
  78.     resid = BASEPICT;
  79.     for (curdir = 0; curdir < NUM_DIRS; ++curdir) {
  80.         for (curframe = 0; curframe < FRAMES_PER; ++curframe) {
  81.         apict[curdir][curframe] =
  82.           (PicHandle)  GetResource((long) 'PICT', resid);
  83.         ++resid;
  84.     }
  85.     }
  86.  
  87.     /*
  88.      * Set the initial state, then draw it into the bitmap.
  89.      */
  90.  
  91.     curdir = 0;
  92.     curframe = 0;
  93.  
  94.     LoadResource(apict[curdir][curframe]);
  95.     topLeft(currect) = topLeft((*apict[curdir][curframe])->picFrame);
  96.     botRight(currect) = botRight((*apict[curdir][curframe])->picFrame);
  97.     OffsetRect(&currect, -currect.right, -currect.top);
  98.  
  99.     GetPort(&saveport);
  100.     SetPort(windoc);
  101.     oldmap.baseAddr = thePort->portBits.baseAddr;
  102.     oldmap.rowBytes = thePort->portBits.rowBytes;
  103.     oldmap.bounds = thePort->portBits.bounds;
  104.     SetPortBits(&offscreen);
  105.     oldvis = NewRgn();
  106.     CopyRgn(thePort->visRgn, oldvis);
  107.     CopyRgn(thePort->clipRgn, thePort->visRgn);
  108.     
  109.     EraseRect(&(thePort->portRect));
  110.     LoadResource(apict[curdir][curframe]);
  111.     DrawPicture(apict[curdir][curframe], &currect);
  112.  
  113.     CopyRgn(oldvis, thePort->visRgn);
  114.     DisposeRgn(oldvis);
  115.     SetPortBits(&oldmap);
  116.     SetPort(saveport);
  117. }
  118.  
  119. /* 
  120.  * redoc() -  redraw the contents of our window, windoc.
  121.  */
  122.  
  123. redoc()
  124. {
  125.     GrafPtr saveport;
  126.  
  127.     BeginUpdate(windoc);
  128.     GetPort(&saveport);
  129.     SetPort(windoc);
  130.  
  131.     CopyBits(&offscreen, &(thePort->portBits),
  132.       &(thePort->portRect), &(thePort->portRect),
  133.       srcCopy, (RgnHandle) 0);
  134.  
  135.     SetPort(saveport);
  136.     EndUpdate(windoc);
  137. }
  138.  
  139. /*
  140.  * draw_idle() - redraw the screen as necessary in an idle loop
  141.  */
  142.  
  143. draw_idle()
  144. {
  145. #define ANIMTIME    6        /* ticks per frame    */
  146.     static unsigned long drawtime = 0L;    /* next time to update the screen    */
  147.     unsigned long nowtime;        /* the current time            */
  148.     GrafPtr saveport;
  149.     BitMap oldmap;    /* the original version of windoc's bitmap */
  150.     RgnHandle oldvis;    /* windoc's previous visible region            */
  151.  
  152.     if (drawtime == 0L) drawtime = TickCount();
  153.  
  154.     nowtime = TickCount();
  155.     if (nowtime < drawtime - 1) {
  156.     return;
  157.     }
  158.  
  159.     /*
  160.      * Prepare to draw into the offscreen bitmap:
  161.      * Select our window;
  162.      * Set our window's bitmap to the offscreen one;
  163.      * Set our window's visible region to the whole window.
  164.      */
  165.  
  166.     GetPort(&saveport);
  167.     SetPort(windoc);
  168.     oldmap.baseAddr = thePort->portBits.baseAddr;
  169.     oldmap.rowBytes = thePort->portBits.rowBytes;
  170.     oldmap.bounds = thePort->portBits.bounds;
  171.     SetPortBits(&offscreen);
  172.     oldvis = NewRgn();
  173.     CopyRgn(thePort->visRgn, oldvis);
  174.     CopyRgn(thePort->clipRgn, thePort->visRgn);
  175.     
  176.     EraseRect(&currect);
  177.  
  178.     /*
  179.      * calculate the new state of the screen,
  180.      * draw it into the offscreen bitmap.
  181.      */
  182.  
  183.     if (++curframe >= FRAMES_PER) {
  184.         curframe = 0;
  185.     }
  186.     if (curdir == 0) {
  187.     if (currect.left >= windoc->portRect.right) {
  188.         curdir = 1;
  189.     }
  190.     } else {
  191.     if (currect.right < windoc->portRect.left) {
  192.         curdir = 0;
  193.     }
  194.     }
  195.     OffsetRect(&currect, vhinc[curdir].h, vhinc[curdir].v);
  196.  
  197.     LoadResource(apict[curdir][curframe]);
  198.     DrawPicture(apict[curdir][curframe], &currect);
  199.  
  200.     /*
  201.      * Restore our window to what it was.
  202.      */
  203.  
  204.     CopyRgn(oldvis, thePort->visRgn);
  205.     DisposeRgn(oldvis);
  206.     SetPortBits(&oldmap);
  207.  
  208.     /*
  209.      * "quickly" (oink, oink!) redraw the screen.
  210.      */
  211.  
  212.     CopyBits(&offscreen, &(thePort->portBits), &(thePort->portRect),
  213.       &(thePort->portRect), srcCopy, (RgnHandle) 0);
  214.  
  215.     drawtime = TickCount() + ANIMTIME;
  216.     SetPort(saveport);
  217. }
  218.